11. JWT¶
是一种使用Json格式的信息作为认证信息的交换方式
JWT是一种安全标准, 即具体实现可能好多种,或者可以把他理解成一种协议
基本思路就是用户提供用户名和密码给认证服务器,服务器验证用户提交信息的合法性;
如果验证成功,会产生并返回一个Token(令牌),用户可以使用这个token访问服务器上受保护的资源。
JWT 的目的不是为了隐藏或者保密数据
在数据传输过程中,使用签名防止中途篡改数据
认证过程
- 依然是用户登录系统
- 服务端验证,将认证信息通过指定的算法(例如HS256)进行加密,例如对用户名和用户所属角色进行加密,加密私钥是保存在服务器端的,将加密后的结果发送给客户端,加密的字符串格式为三个”.” 分隔的字符串 Token,分别对应头部、载荷与签名,头部和载荷都可以通过 base64 解码出来,签名部分不可以;
- 客户端拿到返回的 Token,存储到 local storage 或本地数据库;
- 下次客户端再次发起请求,将 Token 附加到 header 中;
- 服务端获取 header 中的 Token ,通过相同的算法对 Token 中的用户名和所属角色进行相同的加密验证,如果验证结果相同,则说明这个请求是正常的,没有被篡改。这个过程可以完全不涉及到查询 Redis 或其他存储;
JWT是由三部分构成(用.分隔),将这三段信息文本用链接构成了JWT字符串
形如
xxxxx.yyyyy.zzzzz
第一部分:头部(header)
JWT的头部承载的两部分信息:
例如
{ 'typ':'JWT', //声明类型,这里是jwt 'alg':'HS256' //声明加密的算法,通常直接使用HMAC SHA256或RSA }
Header部分的JSON被Base64Url编码,形成JWT的第一部分。
例如
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
第二部分:载荷(payload,该token里携带的有效信息。比如用户id、名字、年龄等等)
这里放声明内容,可以说就是存放沟通讯息的地方,在定义上有3种声明(Claims):
Registered claims(注册声明): 这些是一组预先定义的声明,它们不是强制性的,但推荐使用,以提供一组有用的,可互操作的声明。 其中一些是:iss(发行者),exp(到期时间),sub(主题),aud(受众)等。
Public claims(公开声明): 这些可以由使用JWT的人员随意定义。 但为避免冲突,应在IANA JSON Web令牌注册表中定义它们, 或将其定义为包含防冲突命名空间的URI。
Private claims(私有声明): 这些是为了同意使用它们但是既没有登记,也没有公开声明的各方之间共享信息,而创建的定制声明。
例如:
{ "sub": "1234567890", "name": "Demo", "admin": true }
Playload部分的JSON被Base64Url编码,形成JWT的第二部分。
第三部分:签名(signature)
第三部分signature用来验证发送请求者身份,由前两部分加密形成。
要创建签名部分,您必须采用编码标头,编码有效载荷,秘钥,标头中指定的算法并签名。
例如: 使用HMAC SHA256算法,签名将按照以下方式创建:
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload) + "." + secret)